home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / cops / cops_104 / src / is_something.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-10  |  3.1 KB  |  135 lines

  1. /*
  2.     Usage: is_xxx [-gv] <filename>
  3.  
  4.     This checks determines whether a file is (group or world)
  5.   writable, readable, or SUID, and returns a 0 if false, 1 if true.
  6.   The -g option checks for group status, the -v option prints out
  7.   the result as well.
  8.  
  9.       Permissions bits:          vvv--- Permission bits
  10.                1 = execute        00000
  11.                2 = writable         ^
  12.                4 = readable         + Setuid bits
  13.  
  14.       Setuid bits:
  15.                1 = sticky
  16.                2 = set group id
  17.                4 = set user od
  18.  
  19.     Pete Shipley (shipley@mica.berkeley.edu) gutted my original code,
  20.   made in cleaner and smarter, and combined everything into one compact
  21.   file.  What a deal, huh?  Then I came along and beat up his code and
  22.   made it look ugly again (I changed the is_writeable option to return
  23.   true if _any_ parent directories are writable, not just the target.  So
  24.   you can blame me if you want.  Better yet, just send me a patch if I
  25.   blew it.)
  26.  
  27. */
  28.  
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31.  
  32. #ifdef SETUID
  33. #define G_TEST 02000    /* set group id */
  34. #define W_TEST 04000    /* set user id */
  35. #define G_REPORT_STRING    "%s is set gid\n"
  36. #define W_REPORT_STRING    "%s is set uid\n"
  37. #endif SETUID
  38.  
  39. #ifdef READABLE
  40. #define G_TEST 00040    /* group readable */
  41. #define W_TEST 00004    /* world readable */
  42. #define G_REPORT_STRING    "%s is group readable\n"
  43. #define W_REPORT_STRING    "%s is world readable\n"
  44. #endif READABLE
  45.  
  46. #ifdef WRITABLE
  47. #define G_TEST 00020    /* group writable */
  48. #define W_TEST 00002    /* world writable */
  49. #define G_REPORT_STRING    "%s is group writable\n"
  50. #define W_REPORT_STRING    "%s is world writable\n"
  51. #endif WRITABLE
  52.  
  53. main(argc,argv)
  54. int argc;
  55. char **argv;
  56. {
  57.     register int group = 0,
  58.         verbose = 0,
  59.         xmode;
  60.  
  61.     static struct stat statb;
  62.  
  63.     /* check out arguments */
  64.     if (argc < 2) {
  65.     (void) printf("Usage: %s [-gv] file\n",argv[0]);
  66.     exit(0);
  67.     }
  68.  
  69.     /* parse arguments */
  70.     if (argc > 2) {
  71.     while (argv[1][0] == '-' && argv[1][1] != '\0') {
  72.         if (argv[1][1] == 'g') { group++; argv++; }
  73.         if (argv[1][1] == 'v') { verbose++; argv++; }
  74.     }
  75.     }
  76.  
  77.     /* get stats on file in question */
  78.     if (stat(*++argv,&statb) < 0) {
  79.     perror(*argv);
  80.     exit(2);
  81.     }
  82.  
  83. /*
  84.            the write stuff, so to speak...
  85.      What I'm doing in this mess is to parse the file in question, check out
  86.    whole path; 'cause if anything is world writable, you can compromise.
  87.  
  88. */
  89. #ifdef WRITABLE
  90. {
  91. char foo_dirs[256][256];  /* 256 levels of dirs, max len each 256 chars */
  92. char *foo_file;
  93. int i = 0, j;
  94.  
  95.     foo_file = *argv;
  96.     strcpy(foo_dirs[i++], foo_file);
  97.  
  98.     j=strlen(foo_file) - 1;
  99.     do {
  100.         if (foo_file[j] == '/')
  101.             strncpy(foo_dirs[i++], foo_file, j);
  102.     } while (--j > 0);
  103.  
  104.     for (j = 0; j < i; j++)
  105.         {
  106.         if (stat(foo_dirs[j],&statb) < 0)
  107.             continue;
  108.         else if (!group) {
  109.             if (statb.st_mode & W_TEST)
  110.                 exit(0);
  111.             }
  112.         else if (statb.st_mode & G_TEST)
  113.             exit(0);
  114.         }
  115.  
  116.     exit(1);
  117. }
  118. #endif WRITABLE
  119.  
  120.     /* test premissions on file in question */
  121.     if (group) {
  122.     xmode = statb.st_mode & G_TEST;
  123.     } else {
  124.     xmode = statb.st_mode & W_TEST;
  125.     }
  126.  
  127.     /* report finding */
  128.  
  129.     if(verbose && xmode) {
  130.     (void) printf( (group ? G_REPORT_STRING : W_REPORT_STRING), *argv);
  131.     }
  132.  
  133.     exit(!xmode);
  134. }
  135.